package stack

import (
	"util"
)

const InitCap = 16

type Element interface{}

type Stack struct {
	vals []Element
}

func New() *Stack {
	s := new(Stack)
	s.vals = make([]Element, 0, InitCap)
	return s
}

func (this *Stack) Size() int {
	return len(this.vals)
}

func (this *Stack) Empty() bool {
	return this.Size() == 0
}

func (this *Stack) Top() Element {
	if this.Empty() {
		return nil
	}
	return this.vals[this.Size()-1]
}

func (this *Stack) Push(val Element) {
	this.vals = append(this.vals, val)
}

func (this *Stack) Pop() Element {
	top := this.Top()
	this.vals = this.vals[:this.Size()-1]
	return top
}

func (this *Stack) Clear() {
	l := len(this.vals)
	this.vals = make([]Element, 0, l)
}

func (this *Stack) String() string {
	vals2 := make([]interface{}, len(this.vals))
	for i, val := range this.vals {
		vals2[i] = val
	}
	return util.ToString(vals2) + "Top"
}
